<template>
    <div class="cesium-box">
        <div id="cesiumContainer"></div>
    </div>
</template>

<script setup>
import {onMounted,onBeforeUnmount} from 'vue'
// 引入cesium
import * as Cesium from 'cesium'

// Cesium主类实例
let viewer = null
let tileset = null

// 地图初始化
const mapInit = ()=>{
    // 设置运行时CESIUM_BASE_URL
    window.CESIUM_BASE_URL = '/node_modules/cesium/Build/Cesium/'
    Cesium.Ion.defaultAccessToken =
"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiJiNjZmZDBlNC1kYzQzLTQ3NmUtOTM4ZC1mZWJkMDBlM2M0NjciLCJpZCI6MzQ1MjE5LCJpYXQiOjE3NTkwMzQ1Mjh9.IUWPc2_BOxxeQLUTj8SPeVK_w_SbtRQN64vCZnjoCZI"

    // 创建实例
    viewer = new Cesium.Viewer("cesiumContainer",{
        timeline: false,          // 关闭时间轴
        animation: false,         // 关闭动画控件
        homeButton: false,         // 保留主页按钮
        geocoder: false,          // 关闭搜索
        navigationHelpButton: false,
        infoBox: false,           // 关闭信息框
        fullscreenButton: false ,   // 保留全屏按钮
        selectionIndicator: false,
        scene3DOnly: true,                    // 强制 3D 模式
        sceneMode: Cesium.SceneMode.SCENE3D,  // 初始场景为 3D
        baseLayerPicker: false,   // 关闭底图选择
        imageryProvider:false,//关闭Cesium默认图层
    })

    // 确保移除所有图层
viewer.imageryLayers.removeAll();

    // 创建 天地图夜景影像图层
    const tdtNightLayer = new Cesium.UrlTemplateImageryProvider({
        url:'https://{s}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}.png',
        subdomain:['a','b','c','d']
    })
    // 将 新图层 添加到 viewer实例 的 影像图层(imageryLayers)
    viewer.imageryLayers.addImageryProvider(tdtNightLayer)

    //隐藏版权信息
    viewer._cesiumWidget._creditContainer.style.display = 'none'
}

// 加载3dtiles数据
const load3DTiles = async () => {
    try{
        // 获取3dtiles API调用 (改动一：使用构造函数方式创建tileset ---------------------)
        // 1. 创建 tileset 是异步的
        tileset = new Cesium.Cesium3DTileset({
            url:'/data/zz_3dtiles/tileset.json'
        })
        // 2.readyPromise 是一个 Promise 对象，它会在以下情况完成：
        //        ✅ 成功加载：所有必要的瓦片数据加载完成
        //        ❌ 加载失败：网络错误、数据格式错误等
        await tileset.readyPromise

        // 设置样式
        // const style = new Cesium.Cesium3DTileStyle({
        //     color:{
        //         conditions:[
        //             ["${Floor} < 10.0", "color('#00356A')"], // 深蓝色
        //             ["(${Floor} >= 10.0) && (${Floor} < 20.0)", "color('#0099FF')"], // 亮蓝色
        //             ["(${Floor} >= 20.0) && (${Floor} < 30.0)", "color('#0066CC')"], // 电蓝色
        //             ["(${Floor} >= 30.0) && (${Floor} < 60.0)", "color('#00FFFF')"], // 荧光蓝
        //             ["${Floor} >= 60.0", "color('#0033CC')"], // 深蓝色
        //         ],
        //     }
        // })
        // // 应用样式
        // tileset.style = style

        // 郑州3Dtiles添加到场景
        viewer.scene.primitives.add(tileset)

        // -----------------------------着色器------------------------------
        // 设置着色器
        const customShader = new Cesium.CustomShader({
        lightingModel: Cesium.LightingModel.UNLIT,
        fragmentShaderText: `
            void fragmentMain(FragmentInput fsInput, inout czm_modelMaterial material) {
                float height = fsInput.attributes.positionMC.z;
                
                // 1. 高度渐变颜色(绿色0 -> 红色280m)
                float normalizedHeight = clamp(height / 280.0, 0.0, 1.0);
                vec3 heightColor = mix(vec3(0.0, 1.0, 0.0), vec3(1.0, 0.0, 0.0), normalizedHeight);
                
                // 2. 扫描线效果
                float scanLine = fract(czm_frameNumber / 120.0) * 200.0;  // 扫描线位置
                float distance = abs(height - scanLine);
                
                // 3. 扫描线附近高亮，其他区域显示高度颜色
                if (distance < 10.0) {
                    material.diffuse = vec3(0.0, 1.0, 1.0);  // 黄色高亮
                } else {
                    material.diffuse = heightColor;  // 高度渐变颜色
                }
            }
        `
        })
        tileset.customShader = customShader
        // ---------------------------------------------------------------

        console.log('3DTiles loaded successfully:', tileset)


        // 调整视角
        viewer.zoomTo(tileset)
    }catch(err){
        console.error('加载3Dtiles失败:',err);
    }
}

// 左键事件
const handleCLICK = (e) => {
    console.log('e:',e);
    
    // 拾取该点某物(Cesium3DTileFeature )
    const pickSb = viewer.scene.pick(e.position)
    // 拾取位置
    const pickPos = viewer.scene.pickPosition(e.position)
    console.log("pickSb:",pickSb);
    console.log("pickPos:",pickPos);

    // 得到属性
    const properties = pickSb.getPropertyNames()
    console.log("properties:",properties);

    const pickFeatureFloor = pickSb.getProperty('Floor')
    const pickFeature_Id = pickSb.getProperty('_Id')
    const pickFeatureId = pickSb.getProperty('id')
    const pickFeatureName = pickSb.getProperty('name')
    console.log("pickFeatureFloor:",pickFeatureFloor);
    console.log("pickFeature_Id:",pickFeature_Id);
    console.log("pickFeatureId:",pickFeatureId);
    console.log("pickFeatureName:",pickFeatureName);

    console.log('Feature ID:', pickSb.featureId);
    console.log('Batch ID:', pickSb._batchId);  
    console.log('Show:', pickSb.show);   
    console.log('Color:', pickSb.color); 
    
}

// 设置屏幕空间事件处理
const setScreenSpaceHanlder = () => {
    // 得到 屏幕空间事件处理 实例
    const screenSpaceEventHandler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas)
    // 给 屏幕空间事件处理 实例 添加 监听事件(设置 输入活动)
        // LEFT_CLICK事件
    screenSpaceEventHandler.setInputAction(handleCLICK,Cesium.ScreenSpaceEventType.LEFT_CLICK)
}

onMounted(async ()=>{
    // 确保DOM完全渲染后再初始化
    setTimeout(() => {
        // 地图初始化
        mapInit()

        // 等待viewer创建完成后再加载3dtiles
        setTimeout(async () => {
            await load3DTiles()

            // 设置屏幕空间事件处理
            setScreenSpaceHanlder()
        }, 1000);

        
    }, 100);
    
       
})

// 清理
onBeforeUnmount(()=>{
    if(viewer){
        viewer.destroy()
        viewer = null
    }
})
</script>

<style scoped>
.cesium-box {
height: 100%;
width: 100%;
}
#cesiumContainer {
    height: 100%;
    width: 100%;
}
</style>